class Solution {
public:
    pair<ListNode*, ListNode*> myReverse(ListNode *head, ListNode *tail)
    {
        ListNode *pre = tail->next;
        ListNode *p = head;
        while(pre != tail)
        {
            ListNode *next = p->next;
            p->next = pre;
            pre = p;
            p = next;
        }
        return {tail, head};
    }

    ListNode* reverseKGroup(ListNode* head, int k) {
        ListNode *hair = new ListNode(0);
        hair->next = head;
        ListNode *pre = hair;

        while(head)
        {
            ListNode *tail = pre;
            for(int i = 1; i <= k; ++i)
            {
                tail = tail->next;
                if(!tail) return hair->next;
            }
            ListNode *next = tail->next;
            tie(head, tail) = myReverse(head, tail);
            pre->next = head;
            tail->next = next;
            pre = tail;
            head = tail->next;
        }
        return hair->next;
    }
};